package com.cysyz.mylib.dao.impl;

import com.cysyz.mylib.dao.BaseDao;
import com.cysyz.mylib.dao.PagingResult;
import com.cysyz.mylib.dao.engine.PersistenceEngine;
import com.cysyz.mylib.dao.engine.Query;
import com.cysyz.mylib.dao.support.NativeQueryResultsMapper;

import java.io.Serializable;
import java.util.List;

/**
 * DAO实现类
 *
 * @author 崔勇    cysyz1229@gmail.com
 * @ClassName: BaseDaoImpl
 * @Date 2014-4-24 下午3:15:43
 */

public class BaseDaoImpl implements BaseDao {

    private SqlDaoImpl sqlDao;

    private PersistenceEngine persistenceEngine;

    public void setPersistenceEngine(PersistenceEngine persistenceEngine) {
        this.persistenceEngine = persistenceEngine;
        init(persistenceEngine);
    }

    protected void init(PersistenceEngine persistenceEngine) {
        this.sqlDao = new SqlDaoImpl(persistenceEngine);
    }


    public PersistenceEngine getPersistenceEngine() {
        return persistenceEngine;
    }

    
    public void save(Object entity) {
        persistenceEngine.persist(entity);
    }

    
    public <T> void remove(Class<T> clazz, Serializable id) {
        persistenceEngine.remove(persistenceEngine.getReference(clazz, id));
    }

    
    public void removeByCollection(List list) {
        persistenceEngine.removeByCollection(list);
    }

    
    public void merge(Object entity) {
        persistenceEngine.merge(entity);
    }

    
    public <T> T get(Class<T> clazz, Serializable id) {
        return persistenceEngine.get(clazz, id);
    }


    private List list (String ql, List<Object> params) {
        Query query = getPersistenceEngine().createQuery(ql);
        setParams(params, query);
        return query.getResultList();
    }

    private Object get (String ql, List<Object> params) {
        Query query = getPersistenceEngine().createQuery(ql);
        setParams(params, query);
        return query.getSingleResult();
    }

    private void setParams(List<Object> params, Query query) {
        int i = 1;
        for (Object param : params) {
            query.setParameter(i ++, param);
        }
    }



    public <T> PagingResult<T> sqlListPaging(String ql, List<Object> params, Class<T> resultClazz, String mappingInfo, int page, int maxResult) {
        return sqlDao.listPaging(ql, params, resultClazz, mappingInfo, page, maxResult);
    }

    public <T> T sqlGet(String ql, List<Object> params, Class<T> resultClazz) {
        List<Object[]> result = this.sqlList(ql, params);
        if (result != null && !result.isEmpty() && result.size() > 1) {
            throw new RuntimeException("want one record, but get " + result.size());
        } else if (result == null || result.isEmpty()){
            return null;
        } else {
            return NativeQueryResultsMapper.map(result, resultClazz).get(0);
        }
    }

    public <T> List<T> sqlList(String ql, List<Object> params, Class<T> resultClazz) {
        List<Object[]> result = this.sqlList(ql, params);
        if (result != null) {
            return NativeQueryResultsMapper.map(result, resultClazz);
        } else {
            return null;
        }
    }


    public List<Object[]> sqlList(String ql, List<Object> params) {
        return sqlDao.list(ql, params);
    }

    public void sqlExecute(String ql, List<Object> params) {
        sqlDao.execute(ql, params);
    }


    public <T> long sqlGetCount(String ql, List<Object> params) {
        return sqlDao.getCount(ql, params);
    }
}
